package com.awesome.spring.service;

import com.alibaba.fastjson.JSON;
import com.awesome.spring.bean.Order;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;

/**
 * @program: awesome-spring
 * @description: 事务监听器
 * @author: Alex Wu
 * @createDate: 2025-02-13 16:38
 **/

@Slf4j
@RocketMQTransactionListener
public class OrderTransactionListener implements RocketMQLocalTransactionListener {

    @Autowired
    private OrderService orderService;

    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        try{
            Order order = (Order) o;
            orderService.saveInTransaction(order);
            log.info("执行本地事务: {}", order);
            return RocketMQLocalTransactionState.COMMIT;
        }catch(Exception e){
            log.error("执行本地事务异常", e);
            return RocketMQLocalTransactionState.ROLLBACK;  // 不会回查
//            return RocketMQLocalTransactionState.UNKNOWN; // 未知状态，会回查
        }
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        // 回查 RocketMQLocalTransactionState.UNKNOWN 调用
        Order order = JSON.parseObject(new String((byte[]) message.getPayload()), Order.class);
        log.info("执行事务状态回查: {}", order);
        Order dbOrder = orderService.getOne(new QueryWrapper<Order>().eq("code", order.getCode()));
        if (dbOrder != null) {
            log.info("订单已存在，继续投递");
            return RocketMQLocalTransactionState.COMMIT;
        }else {
            log.info("订单回滚，不再投递");
            log.info("本人人工介入");
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }
}
